package com.mls.medicinereminder.service;

import com.mls.medicinereminder.dao.AvoidWarnDetailsMapper;
import com.mls.medicinereminder.entity.AvoidWarnDetails;
import com.mls.medicinereminder.utils.SearchUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@CacheConfig(cacheNames = "allMedicineDetail")
public class SearchService {

    @Autowired
    AvoidWarnDetailsMapper avoidWarnDetailsMapper;

    /*
    * 如果redis缓存中有对应的数据则从缓存直接获取所有药品信息
    *否则从数据库获取并存入数据库
    * */
    @Cacheable(key = "'all_medicines'")
    public List<AvoidWarnDetails> getAllMedicines(){
        return avoidWarnDetailsMapper.selectAll();
    }

//    编辑距离算法获取相似度达标的字符串
    public List<AvoidWarnDetails> getSearchResults(String sourceStr,List<AvoidWarnDetails> list){
        List<AvoidWarnDetails> results=new ArrayList<AvoidWarnDetails>();
        List<AvoidWarnDetails> medicines=new ArrayList<AvoidWarnDetails>();
        medicines=list;
        for(AvoidWarnDetails medicine:medicines){

            /*
            * 此处的double为相似度最低标准
            * 根据需要设置
            * */
            if(SearchUtils.getsimilarity(sourceStr,medicine.getMedicinename())>=0.3){
                results.add(medicine);
            }
        }
        return results;
    }


//    删除缓存
    @CacheEvict(allEntries = true)
    public void removeAll(){
        System.out.println("123");
    }



  /*自定义模糊搜索算法（相比于编辑距离算法匹配正确率高）
  *sourceStr   输入字符串
  * targetStr   目标字符串
  *MAX_FAULT    设置最大允许sourceStr中与targetStr匹配失败的字符数
  * 算法流程：
  * 1.字符匹配
  * 2.顺序匹配
  */
  public List<AvoidWarnDetails> mySearchResults(String sourceStr,List<AvoidWarnDetails> listTargetStr){
       final int MAX_FAULT = 1;
       int lenSource=sourceStr.length();
       int lenTarget;
       String targetStr;
       List<AvoidWarnDetails> results=new ArrayList<AvoidWarnDetails>();
       loop1:for(AvoidWarnDetails medicine:listTargetStr){   //遍历每一个药品
           int fSum=0;   //当前匹配失败字符数
           int index=0;   //记录前一个匹配正确字符在targetStr中的下标
           boolean matched=false;
           targetStr=medicine.getMedicinename();
           lenTarget=targetStr.length();
           loop2:for(int i=0;i<lenSource;i++){      //遍历输入字符串每个字符
               loop3:for(int j=index;j<lenTarget;j++){
                   if(sourceStr.charAt(i)==targetStr.charAt(j)) {
                       matched=true;
                       index = j + 1;
                       System.out.println(sourceStr.charAt(i));
                       continue loop2;
                   }
               }
                   fSum++;
                   if(fSum>MAX_FAULT) continue loop1;
           }
           if(matched) results.add(medicine);
       }
       return results;
  }

}
